home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource4
/
203_01
/
yam11.asm
< prev
next >
Wrap
Assembly Source File
|
1979-12-31
|
14KB
|
560 lines
PAGE ,132
TITLE 'YAM11: YAM TERMIO ASSMELBY ROUTINES'
;DATE ( 7 nov 85)
; SMALL MODEL
.xlist
INCLUDE \LC\S\DOS.MAC
.list
; interrupt vectors
ser0 equ 0ch ;serial 0 interrupt
ser1 equ 0bh ;serial 1 interrupt
break equ 01bh ;break interrupt
cntlc equ 023h ;control-c handler
lpt equ 017h ;printer status
; monitor functions
get_status equ 02h ;get printer status
; dos functions
commint equ 14h ;monitor serial I/O
dos equ 21h ;ms-dos vector
dcio equ 6h ;dos direct console i/o
get_vector equ 35h ;get interrupt vector
set_vector equ 25h ;set interrupt vector
; i/o port addresses
cntl8259 equ 20h ;control port
mask8259 equ 21h ;interrupt mask register
; offsets to rest of ports
intenreg equ 1 ;interrupt enable
intidreg equ 2 ;interrupt identication
lcreg equ 3 ;line control
modctlreg equ 4 ;modem control
linestreg equ 5 ;line status
modstreg equ 6 ;modem status
; masks and data equates
charrdy equ 01h ;character ready
cr equ 0dh
eoi equ 20h ;non-specific eoi command
idisable equ 0f7h ;serial int disable
ienable equ 08H ;serial int enable
lf equ 0ah
mask3 equ 08h ;int3 disable mask
mask4 equ 010h ;int4 disable mask
mon_conout equ 14 ;funtion code
page_0 equ 0 ;page to output char to
rts equ 02h ;rts on mask
rtsoff equ 0fdh ;rts off mask
rxdmask equ 01h ;interrupt on rx data ready
txrdy equ 20h ;transmitter ready
unmask3 equ 0f7h ;int7 enable mask for 8259
unmask4 equ 0efh ;int4 enable mask for 8259
xoff equ 013h ;^s
;=======================================================
dseg
errflg dw 0 ;error flag for init comm
lowater dw 0 ;copy of LOWWATER
termflg db 0 ;true if in terminal mode
; global variables
extrn Dport:word ;actual data port #
extrn bufst:word ;pointer to buffer start
extrn bufend:word ;pointer to buffer end
extrn bufcq:word ;buffer pointer for modem
extrn bufcdq:word ;buffer pointer for console
extrn Ignrx:word ;Flag which says to throw away chars in rxnono
extrn rxnono:word ;pointer to buffer of characters to ignore
extrn Timeout:word ;timeout before next char rx
extrn Nfree:word ;number of free bytes in buffer
extrn overrun:word ;set if buffer overflows
extrn Wrapped:word ;indicates buffer pointer has looped
extrn Xoffflg:word ;flag indicating Xoff was sent
endds
;=======================================================
pseg
;storage locations in code segment
brk dd 0 ;break vector storage
ctlc dd 0 ;control-c vector storage
;*******************************************************
; return used for break interrupt handlers
cc_hand proc far
iret
cc_hand endp
;*******************************************************
; cause an INT3 for entry into debuggers.
; calling sequence:
; dbgint();
public dbgint
dbgint proc near
int 3
ret
dbgint endp
public init_com
init_com proc near
;*******************************************************
; initialze interrupt vectors for serial port. This will ensure
; all characters from the serial port are not missed. It also resets
; the control-c and break vector so they will not cause an abort back
; to the operating system, leaving interrupt vectors in a unknown state.
; calling sequence:
; init_comm(LOWWATER)
; where LOWWATER is the number of bytes left in the buffer
; at which XOFF is set to the modem.
cld ;auto increment
push bp ;save bp
mov bp,sp
mov ax,[bp+4] ;LOWWATER is parmeter to this routine
mov lowater,ax
cmp si,bx ;check for buffer overflow
pop bp ;done with passed parameters
push es ;save es for caller(required by lattice c or
;very strange things result
push ds ;we muck with ds
cli ;disable interrupts when setting vectors
; save the break interrupt vector. Save area is in code
; segment, thus the segment over-rides.
mov ah,get_vector
mov al,break
int dos
mov word ptr cs:brk,bx ;vector returned in es:bx
mov word ptr cs:brk+2,es
; save the contol-c interrupt vector
mov ah,get_vector
mov al,cntlc
int dos
mov word ptr cs:ctlc,bx ;vector returned in es:bx
mov word ptr cs:ctlc+2,es
; modify old break vector to point to our handler. It must
; return with an iret instruction. Since ds is changed to cs,
; mov will function properly with no segment override.
push cs
pop ds ;set ds=code segment
mov ah,set_vector
mov al,break ;break interrupt vector
mov dx,offset cc_hand ;pointer in ds:dx
int dos
; modify old control-c vector to point to our handler.
mov ah,set_vector
mov al,cntlc ;break interrupt vector
mov dx,offset cc_hand ;pointer in ds:dx
int dos
pop ds
pop es ;restore es for caller
sti ;re-enable system interrupts
ret 2 ;one passed parmeter
init_com endp
public setport
setport proc near
;*******************************************************
; set the interrupt vector for the requested comm port.
; only ports 0 and 1 are supported due to they are the only
; ones which support interrupts on most systems.
; calling sequence:
; setport(port_num);
cli
push bp ;save bp
mov bp,sp
mov bx,[bp+4] ;get modem port number
push ds
push bx
; modify serial interrupt vector to point to its handler
push cs
pop ds ;vector set to ds:dx
mov ah,set_vector
cmp bx,1 ;serial port #1 is at int 3
jz por1
mov al,ser0 ;serial #0 vector
jmp short setvec
por1: mov al,ser1 ;serial #1 interrupt vector
setvec: mov dx,offset ser_int
int dos
;enable 8259 mask
in al,mask8259 ;get mask
pop bx ;check port #
cmp bx,1 ;serial port #1 is at int 3
jz epor1
and al,unmask4 ;enable int4
jmp short emask
epor1: and al,unmask3 ;enable int3
emask: out mask8259,al
pop ds
pop bp
sti ;re-enable system interrupts
ret 2 ;one passed parmeter
setport endp
public resport
resport proc near
;*******************************************************
; reset the interrupt vector for the requested comm port.
; only ports 0 and 1 are supported due to they are the only
; ones which support interrupts on most systems.
; calling sequence:
; resport(port_num);
cli
push bp ;save bp
mov bp,sp
mov bx,[bp+4] ;get modem port number
; mask comm interrupt
in al,mask8259 ;get mask
cmp bx,1 ;serial port #1 is at int 3
jz dpor1
or al,mask4 ;disable int4
jmp short dmask
dpor1: or al,mask3 ;disable int3
dmask: out mask8259,al
; disable trisate buffer for comm interrupt
mov dx,[Dport]
add dx,modctlreg
in al,dx
and al,idisable and rtsoff
out dx,al ;set out2 line false
pop bp
sti ;re-enable system interrupts
ret 2 ;one passed parmeter
resport endp
public enblcm
enblcm proc near
;*******************************************************
; unmask comm interrupt
; enable bit for receive data interrupt and tristate buffer to allow
; interrupts from ACIA. Some of the MSDOS commands such as INT 14
; seem to muck with these bits. Mode is true if in terminal mode otherwise 0.
; Mode sets a flag used by the interrupt routine.
; calling sequence:
; enblcm(mode);
cli
push bp ;save bp
mov bp,sp
mov al,[bp+4] ;get termflag
mov termflg,al
mov dx,[Dport]
add dx,intenreg ;enable serial interrupts
mov al,rxdmask
out dx,al
; enable trisate buffer so interrupts can get to bus
mov dx,[Dport]
add dx,modctlreg
in al,dx
or al,ienable or rts
out dx,al ;set out2 line true
pop bp
sti
ret 2 ;one passed parameter
enblcm endp
public dsblcm
dsblcm proc near
;*******************************************************
; reset interrupt enable register of acia
; calling sequence:
; dsblcm();
cli
mov dx,[Dport]
add dx,intenreg ;offset to enable register
mov al,0 ;disable serial interrupts
out dx,al
sti
ret
dsblcm endp
public res_comm
res_comm proc near
;*******************************************************
; reset interrupt vectors set up in init_comm
; calling sequence:
; res_comm();
cld ;auto increment
cli ;disable interrupts when resetting vectors
push ds ;we muck with ds again
; restore break vector
mov ah,set_vector
mov al,break ;break interrupt vector
mov dx,word ptr brk ;pointer in ds:dx
mov ds,word ptr brk+2
int dos
; restore control-c vector
mov ah,set_vector
mov al,cntlc ;contol-c interrupt vector
mov dx,word ptr ctlc;pointer in ds:dx
mov ds,word ptr ctlc+2
int dos
; re-enable system interrupts
pop ds
sti
ret
res_comm endp
public ser_int
ser_int proc far
;*******************************************************
; serial interrupt routine. This routine gets characters
; from the modem and stuffs them into a circular buffer.
; Global flag Wrapped is set if buffer pointer wrap around
; calling sequence:
; none. this is an interrupt routine
push ax
push dx
push di
push ds
mov ax,dgroup ;ds may be wrong
mov ds,ax
mov dx,[Dport]
add dx,linestreg
in al,dx ;line status
test al,charrdy ;check data ready
jz seoi ;nope, so long
mov dx,[Dport]
in al,dx ;read character
mov di,ds:bufcq ;get bufferpointer
mov [di],al ;save char
inc di ;bump pointer
cmp termflg,0 ;terminal mode does more
jz noterm
call termstuff
; if(bufcq >= bufend)
; {
; Wrapped=TRUE;
; bufcq=bufst;
; }
noterm: cmp di,ds:bufend ;check for end of buffer
jl serdone
mov di,ds:bufst ;bufcq=bufst
mov ds:Wrapped,0ffh ;Wrapped = true
serdone:mov ds:bufcq,di ;update pointer
seoi: mov al,eoi
out cntl8259,al ;set eoi to controller
pop ds
pop di
pop dx
pop ax
intret: sti ;re-enable interrupts
iret
ser_int endp
termstuff proc near
;*******************************************************
; this procedure contains stuff to do in the terminal mode.
; in file transfer mode, this should not be called.
; on entry ax contains last char read, and di contains pointer to
; next free buffer location.
;if (!Ignrx)
; bufcq++;
;else
;if(!index(*bufcq, rxnono))
; bufcq++;
;
push si ;part of interrupt save
cmp ds:Ignrx,0
jz tnfree ;go test Nfree
mov si,offset ds:rxnono
tloop: mov ah,[si] ;scan for match
cmp ah,0 ;end of string
jz tnfree
cmp ah,al
jz found
inc si ;next char
jmp tloop
found: dec di ;set free buffer pointer back one
; Timeout=0;
; if(--Nfree == LOWWATER)
; MOCHAR(Xoffflg=TRUE);
; else if(Nfree==0)
; overrun = TRUE;
;
tnfree: mov ds:timeout,0 ;Timeout = 0
dec ds:Nfree ;number of free bytes -= 1
mov ax,ds:Nfree ;check for < LOWWATER
cmp ax,0 ;test overflow
jnz chklow
mov ds:overrun,1 ;overflow = true
chklow: cmp ax,ds:lowater
jne done ;Nfree grows down
mov ds:Xoffflg,1 ;set flag indicating xoff was sent
mov ax,XOFF ;send Xoff only Nfree=lowater
push ax
call mochr ;send Xoff to modem
done: pop si
ret
termstuff endp
public mirdy
mirdy proc near
;*******************************************************
; if character has come in, bufcq and bufcdq will be different
; if not, zero will be returned in ax, with the zero flag set.
; calling sequence:
; if (mirdy());
mov ax,ds:bufcq
sub ax,[ds:bufcdq]
ret
mirdy endp
public michr
michr proc near
;*******************************************************
; get a character out of the modem input buffer and return in
; ax register. Pointer will be wrapped around to start of buffer
; if it goes past the end.
; calling sequence:
; ch = michr();
mov si,ds:bufcdq ;char out pointer
mov al,[si] ;get char
mov ah,0 ;make integer
inc si ;next buffer location
cmp si,ds:bufend ;check for end of buffer
jl midone ;dont reset pointer
mov si,ds:bufst ;pointer wrapped around
midone: mov ds:bufcdq,si ;bufcdq++
ret
michr endp
public cnsrdy
cnsrdy proc near
;*******************************************************
; console ready function. If a key has been pressed, the zero flag will
; be reset. If not, clear ax and return. This routine is used to
; bypass the DOS ^C handling.
; calling sequence:
; if (cnsrdy());
mov ah,1 ;console status function
int 16h ;key board i/o thru monitor
jnz char ;char rx
nochar: xor ax,ax ;clear ax and set zero flag
char: ret
cnsrdy endp
public cnsin
cnsin proc near
;*******************************************************
; get a char from the console. char is returned in al, with
; with keycode in ah.
; calling sequence:
; ch = cnsin();
mov ah,0
int 16h
ret
cnsin endp
public mochr
mochr proc near
;*******************************************************
; output char modem port. Char is passed on stack as
; first argument. This routine is used rather than the
; monitor because the stupid IBM bios resets the interrupt enable
; line to the interrupt driver.
; calling sequence:
; mochr(ch);
push bp ;save bp
mov bp,sp
mov dx,[Dport] ;wait for txrdy
add dx,linestreg
moloop: in al,dx
test al,txrdy ;wait for hardware
jz moloop
mov al,[bp+4] ;get char to output
mov dx,[Dport] ;transmit port
out dx,al
pop bp
ret 2 ;clean stack
mochr endp
public cochar
cochar proc near
;*******************************************************
; output char on stack to console. Use direct console output
; to bypass control-c, while allowing ansi driver to function
; calling sequence:
; cochar(ch);
push bp ;save bp
mov bp,sp
mov dl,[bp+4] ;get char to output
mov ah,dcio ;direct console i/o
int dos
pop bp
ret 2 ;clean stack
cochar endp
public prtrdy
prtrdy proc near
;*******************************************************
; returns with ax=0 if printer is busy, otherwise ax <> 0
; calling sequence:
; if prtrdy();
mov ah,get_status ;function code
mov dx,0 ;printer port
int lpt ;monitor printer status function
and ah,11111001b ;mask off unused bits
cmp ah,10010000b ;test for ready and select
je rdy ;if =, printer is ready
mov ax,0 ;if not ready, return false
rdy: ret
prtrdy endp
endps
end